home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
utility
/
mu17_ext.zip
/
RLOGIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-07
|
13KB
|
477 lines
/*
** $VER: rlogin.c 1.1 (08.02.94)
**
** remote login command
**
** ⌐ Copyright 1994 by Norbert Pⁿschel
** All Rights Reserved
*/
#include <proto/exec.h>
#include <proto/dos.h>
#include <clib/envoy_protos.h>
#include <pragmas/envoy_pragmas.h>
#include <clib/nipc_protos.h>
#include <pragmas/nipc_pragmas.h>
#include <clib/services_protos.h>
#include <pragmas/services_pragmas.h>
#include <clib/alib_stdio_protos.h>
#include <exec/memory.h>
#include <devices/conunit.h>
#include <dos/dosextens.h>
#include <envoy/envoy.h>
#include <string.h>
#include <debug.h>
struct Library *NIPCBase;
struct Library *ServicesBase;
struct Library *EnvoyBase;
long __oslibversion = 37;
const UBYTE version[] = "$VER: rlogin 1.1 " __AMIGADATE__ ;
UBYTE template[] = "HOST,USERID,GUI/S";
LONG args[3];
#define HBUFFLEN 256
#define UBUFFLEN 32
#define PWDBUFFLEN 16
#ifdef LATTICE
#ifndef __SASC_60
int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
void chkabort(void) { return; } /* really */
#else
void _CXBRK(void) {}
#endif
#endif
void killnl(STRPTR s)
{
while(*s && *s != '\n' && *s != '\r') s++;
*s = '\0';
}
BOOL out(STRPTR s)
{
LONG l = strlen(s);
return((BOOL)(Write(Output(),s,l) == l));
}
BOOL in(STRPTR s,LONG l)
{
LONG r;
r = Read(Input(),s,l-1);
if(r > -1) {
s[r] = '\0';
return(TRUE);
}
else return(FALSE);
}
BOOL rawin(STRPTR s,LONG l)
{
LONG len = 0;
BPTR input = Input();
BPTR output = Output();
BOOL done = FALSE;
SetMode(input,1);
l--;
while(len < l && !done) {
if(Read(input,s,1) != 1) break;
switch(*s) {
case '\b':
if(len) {
Write(output,"\b",1);
len--;
s--;
}
break;
case '\n':
case '\r':
done = TRUE;
default:
if(((*s & 0x7F) > 31 || *s == '\n' || *s == '\r') && *s != 127) {
Write(output," ",1);
len++;
s++;
}
else {
Write(output,"\007",1); /* bell */
}
break;
}
}
Write(output,"\n",1);
if(len == l) done = TRUE;
*s = '\0';
SetMode(input,0);
return(done);
}
#define req(trans,n) (void *)(((UBYTE *)(trans->trans_RequestData))+(n))
#define resp(trans,n) (void *)(((UBYTE *)(trans->trans_ResponseData))+(n))
#define OFFS_CONUNIT 0
#define SIZE_CONUNIT 14*sizeof(WORD)
#define OFFS_RES1 OFFS_CONUNIT+SIZE_CONUNIT
#define SIZE_RES1 sizeof(LONG)
#define OFFS_RES2 OFFS_RES1+SIZE_RES1
#define SIZE_RES2 sizeof(LONG)
#define OFFS_RESPDATA OFFS_RES2+SIZE_RES2
#define OFFS_ARG1 0
#define SIZE_ARG1 sizeof(LONG)
#define OFFS_ARG2 OFFS_ARG1+SIZE_ARG1
#define SIZE_ARG2 sizeof(LONG)
#define OFFS_REQDATA OFFS_ARG2+SIZE_ARG2
#define CONUNIT(ci) (APTR)&(((struct ConUnit *)(ci.ci_IOStdReq->io_Unit))->cu_XCP)
struct ConInfo {
struct MinList ci_Actions;
BOOL ci_IsOpen;
struct Entity *ci_Dest;
struct Entity *ci_Source;
struct MsgPort *ci_Handler;
struct MsgPort *ci_Port;
struct IOStdReq *ci_IOStdReq;
} ci;
void do_packet(struct DosPacket *dp);
void do_transaction(struct Transaction *trans);
int main(int argc,char **argv)
{
UBYTE hname[HBUFFLEN];
UBYTE uname[UBUFFLEN];
UBYTE pwd[PWDBUFFLEN];
int retval,rc2 = ERROR_NO_FREE_STORE;
UBYTE ename[32];
BYTE signum;
ULONG mask,rmask;
#define bmask \
(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)
struct Transaction *trans;
struct Message *msg;
struct DosPacket *dp;
struct InfoData *id;
struct RDArgs *rda;
if(argc == 0) return(20); /* no WB ! */
rda = ReadArgs(template,args,0);
if(rda == 0) return(10);
if(args[0]) { /* host given */
strncpy(hname,(STRPTR)(args[0]),HBUFFLEN);
}
if(args[1]) { /* user given */
strncpy(uname,(STRPTR)(args[1]),UBUFFLEN);
}
if(args[2]) {
EnvoyBase = OpenLibrary("envoy.library",37);
if(EnvoyBase) {
if(args[0] == 0) {
retval =
HostRequest(HREQ_Buffer,hname,
HREQ_BuffSize,HBUFFLEN,
TAG_DONE) ? 0 : 5;
}
else retval = 0;
if(retval == 0) {
retval =
LoginRequest(LREQ_NameBuff,uname,
LREQ_NameBuffLen,UBUFFLEN,
LREQ_PassBuff,pwd,
LREQ_PassBuffLen,PWDBUFFLEN,
TAG_DONE) ? 0 : 5;
}
CloseLibrary(EnvoyBase);
}
else retval = 20;
}
else {
if(args[0] == 0) {
retval = (out("Host : ") && in(hname,HBUFFLEN)) ? 0 : 5;
}
else retval = 0;
if(retval == 0 && args[1] == 0) {
retval = (out("User : ") && in(uname,UBUFFLEN)) ? 0 : 5;
}
else retval = 0;
if(retval == 0) {
retval = (out("Password: \033[8m") &&
rawin(pwd,PWDBUFFLEN) &&
out("\033[28m")) ? 0 : 5;
}
if(retval == 0) {
killnl(hname);
killnl(uname);
killnl(pwd);
}
debug2("Password: %s\n",pwd);
}
FreeArgs(rda);
if(retval) {
out("Login failed.\n");
return(retval);
}
if(!IsInteractive(Input()) || !IsInteractive(Output())) return(20);
ci.ci_Handler = ((struct FileHandle *)(BADDR(Input())))->fh_Type;
ci.ci_IOStdReq = 0;
id = (struct InfoData *)AllocMem(sizeof(struct InfoData),MEMF_PUBLIC);
if(id) {
if(DoPkt(ci.ci_Handler,ACTION_DISK_INFO,MKBADDR(id),0,0,0,0)) {
ci.ci_IOStdReq = (struct IOStdReq *)(id->id_InUse);
}
FreeMem(id,sizeof(struct InfoData));
}
retval = 20;
ci.ci_Port = CreateMsgPort();
if(ci.ci_Port) {
signum = AllocSignal(-1);
if(signum != -1) {
NIPCBase = OpenLibrary("nipc.library",39);
if(NIPCBase) {
ServicesBase = OpenLibrary("services.library",37);
if(ServicesBase) {
sprintf(ename,"Remote Login %ld",
((struct Process *)FindTask(0))->pr_TaskNum);
ci.ci_Source = CreateEntity(ENT_Name,ename,
ENT_Public,TRUE,
ENT_Signal,signum,
TAG_DONE);
if(ci.ci_Source) {
debug("Entity created\n");
ci.ci_Dest = FindService(*hname ? hname : 0,
"Remote Login",ci.ci_Source,
FSVC_UserName,uname,
FSVC_PassWord,pwd,
FSVC_Error,&rc2,
TAG_DONE);
if(ci.ci_Dest) {
debug("Service found\n");
trans = AllocTransaction(TRN_AllocReqBuffer,
SIZE_CONUNIT+strlen(ename)+1,
TAG_DONE);
if(trans) {
debug("Transaction allocated\n");
if(ci.ci_IOStdReq) {
trans->trans_Command = 1;
CopyMem(CONUNIT(ci),req(trans,OFFS_CONUNIT),SIZE_CONUNIT);
}
strcpy((STRPTR)req(trans,SIZE_CONUNIT),ename);
DoTransaction(ci.ci_Dest,ci.ci_Source,trans);
retval = trans->trans_Error;
FreeTransaction(trans);
if(retval == 0) {
NewList((struct List *)&(ci.ci_Actions));
ci.ci_IsOpen = TRUE;
mask = (1L<<signum)|(1L<<ci.ci_Port->mp_SigBit)|bmask;
do {
rmask = Wait(mask);
if(rmask &= bmask) goto do_break;
do {
if(rmask = bmask & SetSignal(0,bmask)) {
do_break:
trans = AllocTransaction(TAG_DONE);
if(trans) {
trans->trans_Command = rmask>>12;
BeginTransaction(ci.ci_Dest,ci.ci_Source,trans);
}
}
if(msg = GetMsg(ci.ci_Port)) {
dp = (struct DosPacket *)(msg->mn_Node.ln_Name);
do_packet(dp);
}
if(trans = GetTransaction(ci.ci_Source)) {
if(trans->trans_Type == TYPE_RESPONSE) {
FreeTransaction(trans);
}
else {
do_transaction(trans);
}
}
} while(msg != 0 || trans != 0);
} while(ci.ci_IsOpen);
out("\n");
}
}
LoseEntity(ci.ci_Dest);
}
DeleteEntity(ci.ci_Source);
}
CloseLibrary(ServicesBase);
}
CloseLibrary(NIPCBase);
}
FreeSignal(signum);
}
DeleteMsgPort(ci.ci_Port);
}
if(retval) {
out("Login failed.\n");
SetIoErr(rc2);
}
return(retval);
}
struct ActionNode {
struct MinNode an_Node;
struct DosPacket *an_Packet;
struct Transaction *an_Trans;
};
void do_packet(struct DosPacket *dp)
{
struct ActionNode *an;
struct Transaction *trans;
an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
while(an->an_Node.mln_Succ) {
if(an->an_Packet == dp) break;
an = (struct ActionNode *)(an->an_Node.mln_Succ);
}
if(an->an_Node.mln_Succ) {
trans = an->an_Trans;
if(ci.ci_IOStdReq) {
CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
}
*(LONG *)resp(trans,OFFS_RES1) = dp->dp_Res1;
*(LONG *)resp(trans,OFFS_RES2) = dp->dp_Res2;
ReplyTransaction(trans);
Remove((struct Node *)an);
FreeMem(an,sizeof(struct ActionNode));
}
FreeDosObject(DOS_STDPKT,dp);
}
void do_transaction(struct Transaction *trans)
{
struct ActionNode *an;
struct DosPacket *dp;
struct Message *msg;
if(trans->trans_Command == 0) {
an = (struct ActionNode *)AllocMem(sizeof(struct ActionNode),0);
if(an) {
dp = (struct DosPacket *)AllocDosObjectTags(DOS_STDPKT,TAG_DONE);
if(dp) {
dp->dp_Type = *(LONG *)req(trans,OFFS_ARG1);
switch(dp->dp_Type) {
case ACTION_READ:
case ACTION_WRITE:
case 2001: /* ACTION_FORCE */
case 2002: /* ACTION_STACK */
case 2003: /* ACTION_QUEUE */
dp->dp_Arg1 = 0;
dp->dp_Arg3 = *(LONG *)req(trans,OFFS_ARG2);
if(dp->dp_Type == ACTION_READ) {
dp->dp_Arg2 = (LONG)resp(trans,OFFS_RESPDATA);
}
else {
dp->dp_Arg2 = (LONG)req(trans,OFFS_REQDATA);
}
break;
case ACTION_WAIT_CHAR:
case ACTION_SCREEN_MODE:
case 2004: /* ACTION_DROP */
dp->dp_Arg1 = *(LONG *)req(trans,OFFS_ARG2);
break;
default:
if(ci.ci_IOStdReq) {
CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
}
*(LONG *)resp(trans,OFFS_RES1) =
(dp->dp_Type == ACTION_SEEK) ? -1 : DOSFALSE;
*(LONG *)resp(trans,OFFS_RES2) = ERROR_ACTION_NOT_KNOWN;
ReplyTransaction(trans);
FreeDosObject(DOS_STDPKT,dp);
FreeMem(an,sizeof(struct ActionNode));
return;
}
an->an_Packet = dp;
an->an_Trans = trans;
AddTail((struct List *)&(ci.ci_Actions),(struct Node *)an);
dp->dp_Port = ci.ci_Port;
PutMsg(ci.ci_Handler,dp->dp_Link);
return;
}
FreeMem(an,sizeof(struct ActionNode));
}
}
else {
an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
while(an->an_Node.mln_Succ) {
dp = an->an_Packet;
AbortPkt(ci.ci_Handler,dp);
if(ci.ci_IOStdReq) {
CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
}
if(dp->dp_Type == ACTION_READ || dp->dp_Type == ACTION_WRITE) {
*(LONG *)resp(an->an_Trans,OFFS_RES1) = -1;
}
else {
*(LONG *)resp(an->an_Trans,OFFS_RES1) = DOSFALSE;
}
*(LONG *)resp(an->an_Trans,OFFS_RES2) = ERROR_INVALID_LOCK;
ReplyTransaction(an->an_Trans);
an = (struct ActionNode *)(an->an_Node.mln_Succ);
}
while(!IsListEmpty((struct List *)&(ci.ci_Actions))) {
WaitPort(ci.ci_Port);
while(msg = GetMsg(ci.ci_Port)) {
dp = (struct DosPacket *)(msg->mn_Node.ln_Name);
an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
while(an->an_Node.mln_Succ) {
if(an->an_Packet == dp) break;
an = (struct ActionNode *)(an->an_Node.mln_Succ);
}
if(an->an_Node.mln_Succ) {
Remove((struct Node *)an);
FreeMem(an,sizeof(struct ActionNode));
}
FreeDosObject(DOS_STDPKT,dp);
}
}
ReplyTransaction(trans);
ci.ci_IsOpen = FALSE;
}
}